package com.ruoyi.vqms.socket;

import cn.hutool.extra.spring.SpringUtil;
import com.ruoyi.vqms.service.IVQMSLedService;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SocketHandler extends ByteToMessageDecoder {
    // 用来保存所有的客户端连接
    private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    // 设备连接超时时间（秒）
    private static final int DEVICE_TIMEOUT = 60;

    // 设备最后活跃时间记录
    private static Map<String, Long> deviceLastActiveTime = new HashMap<>();
    @Autowired
    private RedisTemplate<String, Object> redisCache;
    IVQMSLedService ivqmsLedService = SpringUtil.getBean(IVQMSLedService.class);

    // 当Channel中有新的事件消息会自动调用
    @Autowired
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            // 更新设备活跃时间
            String channelId = ctx.channel().id().asLongText();
            deviceLastActiveTime.put(channelId, System.currentTimeMillis());

            ivqmsLedService.handleLink(ctx, msg);
            System.out.println("led设备连接消息ctx----》"+ctx.toString());
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }


    // 当有新的客户端连接服务器之后，会自动调用这个方法
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // 将新的通道加入到clients
        clients.add(ctx.channel());
//        System.out.println("设备连接: " + ctx.channel().id().asLongText());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        String channelId = ctx.channel().id().asLongText();
        DeviceChannelMap.removeByChannelId(channelId);
        clients.remove(ctx.channel());
        deviceLastActiveTime.remove(channelId);
        ctx.close();
    }

    @Override
    public void handlerRemoved0(ChannelHandlerContext ctx) throws Exception {
//        System.out.println("设备断开连接: " + ctx.channel().id().asLongText());
        String channelId = ctx.channel().id().asLongText();
        DeviceChannelMap.removeByChannelId(channelId);
        clients.remove(ctx.channel());
        deviceLastActiveTime.remove(channelId);
    }

    // 处理空闲事件，检测连接是否超时
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                // 读超时，检查是否需要断开连接
                String channelId = ctx.channel().id().asLongText();
                Long lastActiveTime = deviceLastActiveTime.get(channelId);
                if (lastActiveTime != null && (System.currentTimeMillis() - lastActiveTime) > (DEVICE_TIMEOUT * 1000)) {
                    System.out.println("设备连接超时，关闭连接: " + channelId);
                    ctx.close();
                }
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        if(byteBuf.readableBytes() > 8){
            list.add(byteBuf.readLong());
        }
    }

}
